package com.lc.core.comparator;


import com.lc.utils.UCharUtil;
import com.lc.utils.UStringUtil;

import java.io.Serializable;
import java.util.Comparator;
import java.util.List;

/**
 * 版本比较器<br>
 * 比较两个版本的大小<br>
 * 排序时版本从小到大排序，既比较时小版本在前，大版本在后<br>
 * 支持如：1.3.20.8，6.82.20160101，8.5a/8.5c等版本形式<br>
 * 参考：https://www.cnblogs.com/shihaiming/p/6286575.html
 *
 * @author LC
 * @since 0.1
 */
public class VersionComparator implements Comparator<String>, Serializable {
    private static final long serialVersionUID = 8083701245147495562L;

    /**
     * 单例
     */
    public static final VersionComparator INSTANCE = new VersionComparator();

    /**
     * 默认构造
     */
    public VersionComparator() {
    }

    // -----------------------------------------------------------------------------------------------------

    /**
     * 比较两个版本<br>
     * null版本排在最小：既：
     * <pre>
     * compare(null, "v1") &lt; 0
     * compare("v1", "v1")  = 0
     * compare(null, null)   = 0
     * compare("v1", null) &gt; 0
     * compare("1.0.0", "1.0.2") &lt; 0
     * compare("1.0.2", "1.0.2a") &lt; 0
     * compare("1.13.0", "1.12.1c") &gt; 0
     * compare("V0.0.20170102", "V0.0.20170101") &gt; 0
     * </pre>
     *
     * @param version1 版本1
     * @param version2 版本2
     */
    @Override
    public int compare(String version1, String version2) {
        if (version1 == version2) {
            return 0;
        }
        if (version1 == null && version2 == null) {
            return 0;
        } else if (version1 == null) {// null视为最小版本，排在前
            return -1;
        } else if (version2 == null) {
            return 1;
        }

        final List<String> v1s = UStringUtil.split(version1, UCharUtil.DOT);
        final List<String> v2s = UStringUtil.split(version2, UCharUtil.DOT);

        int diff = 0;
        int minLength = Math.min(v1s.size(), v2s.size());// 取最小长度值
        String v1;
        String v2;
        for (int i = 0; i < minLength; i++) {
            v1 = v1s.get(i);
            v2 = v2s.get(i);
            // 先比较长度
            diff = v1.length() - v2.length();
            if (0 == diff) {
                diff = v1.compareTo(v2);
            }
            if (diff != 0) {
                //已有结果，结束
                break;
            }
        }

        // 如果已经分出大小，则直接返回，如果未分出大小，则再比较位数，有子版本的为大；
        return (diff != 0) ? diff : v1s.size() - v2s.size();
    }

    @Override
    public boolean equals(final Object object) {
        if (this == object) {
            return true;
        }
        if (null == object) {
            return false;
        }
        if (object.getClass().equals(this.getClass())) {
            final VersionComparator other = (VersionComparator) object;
            return this.equals(other);
        }
        return false;
    }
}

